<?php
/**
 * Created by PhpStorm.
 * User: lee
 * Date: 2018/4/4
 * Time: 下午2:37
 */

namespace Biz\module\Classes;

use Biz\model\GoodsSku as mGoodsSku;
use Biz\model\ShopBasicInfo as mShopBasicInfo;
use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderOperateLog as mOrderOperateLog;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\OrderRefundQueue as mOrderRefundQueue;
use Biz\module\Classes\Order as clsOrder;
use Biz\module\Classes\OrderGoods as clsOrderGoods;
use Biz\module\Packages\CustomerService\SmallEnergy as csSmallEnergy;
use Biz\service\Event;
use Biz\service\settlement\SettlementTransaction as sSettlementTransaction;
use Biz\service\trade\ShopCourier as sShopCourier;
use Biz\tools\Amount;
use Biz\tools\OrderNo as toolOrderNo;
use Biz\validate\trade\OrderRefund as vOrderRefund;
use Doraemon\amqp\Queue as aQueue;
use Doraemon\service\User as sUser;
use Doraemon\tools\Log as tLog;
use Medoo\Medoo;

class OrderRefund
{
    //是否有退款中的申请的常量
    const REFUNDING_NO = 1;//没有退款中的申请
    const REFUNDING_YES = 2;//有退款中的申请
    const REFUNDING_RIGHTS_IN = 3;//有维权中的申请
    const REFUND_WAIT_APPLY = 4;//有待审核的退款列表
    const COMPANY_GROUP_ID = 'jh_1000_9999';


    public function getRefundReasonList($orderStatus = null, $typeRefund = null, $receiptStatus = null)
    {
        $result = [];

        $reasonList = mOrderRefund::$reasonList;

        //获取全部原因
        if (empty($orderStatus)) {
            return $reasonList;
        }


        //根据条件筛选需要的原因
        $list = [];

        if ($orderStatus == mOrder::STATUS_WAIT_SEND) {

            $list = $reasonList['group-1'];

        }

        if ($orderStatus == mOrder::STATUS_SEND_OUT || $orderStatus == mOrder::STATUS_SUCCESS) {

            if ($typeRefund == mOrderRefund::TYPE_REFUND_AMOUNT) {

                if ($receiptStatus == mOrderRefund::RECEIPT_STATUS_NO) {

                    $list = $reasonList['group-2'];

                }
                if ($receiptStatus == mOrderRefund::RECEIPT_STATUS_YES) {

                    $list = $reasonList['group-3'];

                }
            }

            if ($typeRefund == mOrderRefund::TYPE_REFUND_ALL) {
                $list = $reasonList['group-4'];

            }
        }

        if (!empty($list)) {
            foreach ($list as $id => $desc) {

                $info = [
                    'id' => $id,
                    'desc' => $desc,
                    'tip' => ''
                ];

                if ($id == mOrderRefund::REFUND_REASON_40) {
                    $info['tip'] = '退货运费需由买家承担';
                }
                $result[] = $info;
            };
        }


        return $result;
    }

    public function getRefundSkuInfo($uid, $orderNo, $skuId, $reason = -1)
    {
        $data = [];

        $orderSku = self::getOrderSkuInfo($uid, $orderNo, $skuId, false);

        if (empty($orderSku['sku_id'])) {
            throw new \Exception('商品sku不存在');
        }

        $data['title'] = $orderSku['title'];
        $data['sku_id'] = $skuId;
        $data['sku_desc'] = $orderSku['sku_desc'];
        $data['cover_img'] = $orderSku['cover_img_thumb_url'];

        $checkRefund = self::checkCanApplyRefund($orderSku);


        if ($checkRefund) {
            $canRefund = self::getSkuCanRefundAmount($orderSku, null, $reason);
            $data['max_refund_amount'] = $canRefund['refund_max_amount'];
            $data['shipping_fee'] = $canRefund['refund_shipping_fee'];
        } else {
            $data['max_refund_amount'] = 0;
            $data['shipping_fee'] = 0;
        }

        //如果部分发货的订单，那么则需要拿到skuid的真正发货状态
        if ($orderSku['order_info']['status'] == mOrder::STATUS_SEND_PART_OUT) {
            $skuIsShip = clsOrderGoods::checkSkuIsDeliveryIncludePartShip($orderNo, $orderSku['sku_id'], $orderSku['order_info']);
            if ($skuIsShip === 1) {
                $data['order_status'] = mOrder::STATUS_WAIT_SEND;
            } elseif ($skuIsShip === 2) {
                $data['order_status'] = mOrder::STATUS_SEND_OUT;
            }

        } else {
            $data['order_status'] = $orderSku['order_info']['status'];
        }


        return $data;
    }


    public function applyRefund($uid, $orderNo, $skuId, $data, $needOrderOpLog = true)
    {
        //查询申请的退款原订单信息，包括商品信息
        $orderSku = self::getOrderSkuInfo($uid, $orderNo, $skuId);

        //判断此次提交是否可以通过申请
        $checkRefund = self::checkCanApplyRefund($orderSku);

        if (!$checkRefund) {
            throw new \Exception('该sku不可申请退款');
        }

        $refundOrderNo = $this->refundForm($orderSku, $data, 'create', 'insert', false, $needOrderOpLog);

        return $refundOrderNo;
    }

    public function changeRefund($uid, $refundOrderNo, $data)
    {
        //根据退款单查询退款单信息以及订单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);

        if ($orderSku['uid'] != $uid) {
            throw new \Exception('该退款单不允许修改');
        }

        $checkChange = self::checkCanChangeApply($orderSku);

        if (!$checkChange) {
            throw new \Exception('该退款单不允许修改');
        }

        $this->refundForm($orderSku, $data, 'update', 'update', true);

    }

    protected function refundForm(&$orderSku, $data, $scenes = 'create', $method = 'insert', $isEdit = false, $needOrderOpLog = true)
    {

        //sku是否发货
        $skuIsShip = clsOrderGoods::checkSkuIsDeliveryIncludePartShip($orderSku['order_no'], $orderSku['sku_id'], $orderSku['order_info']);

        if ($skuIsShip === 1) {
            //如果未发货，则需要退全款
            $data['type_refund'] = mOrderRefund::TYPE_REFUND_AMOUNT;
            $data['receipt_status'] = mOrderRefund::RECEIPT_STATUS_NORMAL;

            //计算可以退款的金额
            $canRefund = self::getSkuCanRefundAmount($orderSku);

            $data['refund_amount'] = $canRefund['refund_apply_amount'];

        } elseif ($skuIsShip === 2) {
            //计算可以退款的金额
            $canRefund = self::getSkuCanRefundAmount($orderSku, $data['refund_amount'], $data['reason']);
        } else {
            throw new \Exception('系统异常');
        }

        //如果用户收到货，且要申请退货退款，则收货状态为已收货
        if ($data['type_refund'] == mOrderRefund::TYPE_REFUND_ALL) {
            $data['receipt_status'] = mOrderRefund::RECEIPT_STATUS_YES;
        }

        //初始化订单状态数据
        $data['order_status'] = $orderSku['order_info']['status'];


        //验证此次表单是否规则正确
        if (!vOrderRefund::validate($data, $scenes)) {
            $msg = vOrderRefund::firstError();
            throw new \Exception($msg);
        }

        if ($canRefund['refund_rmb_total'] == 0) {

            //添加申请退款金额出现异常微信通知通知
            aQueue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_SYSTEM,
                "content" => vsprintf('申请退款出现计算金额异常,info=%s %s %s %s', [
                    $orderSku['uid'],
                    $orderSku['order_no'],
                    isset($orderSku['refund_info']) ? $orderSku['refund_info']['refund_order_no'] : '',
                    json_encode($canRefund, JSON_UNESCAPED_UNICODE)
                ])
            ], aQueue::QUEUE_BIZ);

            throw new \Exception('可退金额出现异常，请正确输入');
        }


        {
            //插入退款基本表
            $nowTime = time();
            $refundData = [];

            if ($isEdit) {
                $refundOrderNo = $orderSku['refund_info']['refund_order_no'];
            } else {
                //生成退款单号
                $refundOrderNo = toolOrderNo::genRefundNo($orderSku['order_no']);

                $refundData = [
                    'uid' => $orderSku['uid'],
                    'refund_order_no' => $refundOrderNo,
                    'order_no' => $orderSku['order_no'],
                    'goods_id' => $orderSku['goods_id'],
                    'sku_id' => $orderSku['sku_id'],
                    'shop_id' => $orderSku['shop_id'],
                    'title' => $orderSku['title'],
                    'cover_img' => $orderSku['cover_img'],
                    'sku_desc' => $orderSku['sku_desc'],
                    'addtime' => date('Y-m-d H:i:s'),

                ];
            }

            $refundData = array_merge($refundData, [
                'reason' => $data['reason'],
                'type_refund' => $data['type_refund'],
                'receipt_status' => $data['receipt_status'],
                'apply_amount' => $data['refund_amount'],
                'apply_rmb' => $canRefund['refund_sku_pay_amount'],
                'apply_integral' => $canRefund['refund_integral'],
                'apply_integral_amount' => $canRefund['refund_integral_amount'],
                'apply_packet_amount' => $canRefund['refund_packet_amount'],
                'apply_shipping_amount' => $canRefund['refund_shipping_fee'],
                'apply_coupon_amount' => $canRefund['refund_coupon_amount'],
                'apply_activity_allowance' => $canRefund['refund_activity_allowance'],
                'refund_amount' => $data['refund_amount'],
                'refund_rmb' => $canRefund['refund_sku_pay_amount'],
                'refund_integral' => $canRefund['refund_integral'],
                'refund_integral_amount' => $canRefund['refund_integral_amount'],
                'refund_packet_amount' => $canRefund['refund_packet_amount'],
                'refund_coupon_amount' => $canRefund['refund_coupon_amount'],
                'refund_activity_allowance' => $canRefund['refund_activity_allowance'],
                'refund_commission_amount' => $canRefund['refund_commission_amount'],
                'refund_shipping_amount' => $canRefund['refund_shipping_fee'],
                'refund_remark' => $data['refund_remark'],
                'refund_images_content' => $data['images_content'],
                'auto_agree_time' => date('Y-m-d H:i:s', $nowTime + mOrderRefund::AUTO_AGREE_TIME),
                'status' => mOrderRefund::STATUS_NORMAL
            ]);


            mOrderRefund::createOrEdit($refundOrderNo, $refundData, $scenes);

        }



        {
            //修改订单表和订单商品表关于退款的部分字段
            //修改order表
            $refundOpcode = [
                'refund_amount[+]' => $canRefund['refund_rmb_total']
            ];
            if ($isEdit) {
                $refundOpcode = [
                    'refund_amount[-]' => (($orderSku['refund_info']['refund_rmb'] + $orderSku['refund_info']['refund_shipping_amount']) - $canRefund['refund_rmb_total'])
                ];
            }

            self::syncRefundAmountRecord($orderSku['order_no'], $orderSku['sku_id'], [
                'refund_order_no' => $refundOrderNo,
                'refund_status' => mOrderGoods::REFUND_STATUS_CAN_NOT_REFUND,
                'refund_amount' => $canRefund['refund_sku_pay_amount']
            ], array_merge([
                'refunding_status' => mOrder::REFUNDING_STATUS_PROCESS
            ], $refundOpcode));

            //用户成功申请退款事件
            Event::push(Event::ORDER_REFUND_USER_APPLY_SUCCESS, array_merge([
                'uid' => $orderSku['uid'],
                'order_no' => $orderSku['order_no'],
                'refund_order_no' => $refundOrderNo,
                'goods_id' => $orderSku['goods_id'],
                'sku_id' => $orderSku['sku_id'],
                'reason' => $data['reason'],
                'type_refund' => $data['type_refund'],
                'receipt_status' => $data['receipt_status'],
                'refund_remark' => $data['refund_remark'],
                'refund_amount' => $data['refund_amount'],
                'images_content' => $data['images_content'],
                'is_change' => (int)$isEdit,
                'need_order_oplog' => (int)$needOrderOpLog,
                'now_time' => date('Y-m-d H:i:s'),
                'uniq_idx' => ['refund_order_no', 'event_tag', 'is_change', 'now_time']
            ], $refundData));


            tLog::refund_refund_info($isEdit ? '修改退款申请成功' : '添加退款申请成功', [
                'refund_order_no' => $refundOrderNo,
                'params' => [
                    'order_sku' => $orderSku,
                    'data' => $data,
                    'scenes' => $scenes,
                    'method' => $method,
                    'isedit' => (int)$isEdit
                ],
                'can_refund' => $canRefund,
                'refund_data' => $refundData,
            ]);

            return $refundOrderNo;

        }

    }

    public function cancelRefund($uid, $refundOrderNo, $isSys = false, $isForce = false)
    {
        //查询退款单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);


        //如果是强制取消，则不需要判断当前状态

        //判断是否可以取消退款
        if (!$isSys && $orderSku['refund_info']['uid'] != $uid) {
            throw new \Exception('不可操作该退款单');
        }

        if (!$isForce) {


            if (!in_array($orderSku['refund_info']['status'], mOrderRefund::$refundIngStatusList)) {
                throw new \Exception('不可操作该退款单');
            }

        }

        //操作退款记录表
        $result = mOrderRefund::update([
            'status' => ($orderSku['refund_info']['type_refund'] == mOrderRefund::TYPE_REFUND_AMOUNT) ? mOrderRefund::STATUS_CANCEL : mOrderRefund::STATUS_RETURN_GOODS_CANCEL,
            'cancel_time' => date('Y-m-d H:i:s')
        ], ['refund_order_no' => $refundOrderNo]);

        if ($result->rowCount() == 0) {
            throw new \Exception('操作异常');
        }

        //变更可以申请退款的状态
        mOrderGoods::update([
            'refund_status' => mOrderGoods::REFUND_STATUS_CAN_REFUND
        ], ['order_no' => $orderSku['order_no'], 'sku_id' => $orderSku['sku_id']]);


        if ($orderSku['refund_info']['status'] !== mOrderRefund::STATUS_REJECT) {

            self::syncRefundAmountRecord($orderSku['order_no'], $orderSku['sku_id'], [
                'refund_amount' => 0
            ], [
                'refund_amount[-]' => ($orderSku['refund_info']['refund_rmb'] + $orderSku['refund_info']['refund_shipping_amount']),
            ]);

        }

        //用户取消退款的事件
        Event::push(Event::ORDER_REFUND_USER_CANCEL_SUCCESS, [
            'uid' => $orderSku['uid'],
            'order_no' => $orderSku['order_no'],
            'refund_order_no' => $refundOrderNo,
            'goods_id' => $orderSku['goods_id'],
            'sku_id' => $orderSku['sku_id'],
            'type_refund' => $orderSku['refund_info']['type_refund'],
            'is_sys' => (int)$isSys,
            'uniq_idx' => ['refund_order_no', 'event_tag']
        ]);

        //增加操作日志
        $textContent = '取消退款';
        if ($orderSku['refund_info']['receipt_status'] == mOrderRefund::RECEIPT_STATUS_YES) {
            if ($isSys) {
                $textContent = '系统自动取消退货';
            } else {
                $textContent = '取消退货';
            }

        }

        $result = mOrderOperateLog::createLog($orderSku['shop_id'], $orderSku['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER_REFUND, [
            'operate_type' => mOrderOperateLog::OPERATE_TYPE_CANCEL_REFUND_AMOUNT,
            'operate_user_type' => $isSys ? mOrderOperateLog::OPERATE_USERTYPE_SYS : mOrderOperateLog::OPERATE_USERTYPE_USER,
            'operate_uid' => $isSys ? 0 : $uid,
        ], $refundOrderNo, $textContent, '');

        if ($result->rowCount() == 0) {
            throw new \Exception('取消退款错误');
        }


    }

    public function fillLogistics($uid, $refundOrderNo, $data)
    {
        $nowTime = time();

        //判断表单是否正确
        if (!vOrderRefund::validate($data, 'fillLogistics')) {
            $msg = vOrderRefund::firstError();
            throw new \Exception($msg);
        }

        //查询退款单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);

        //判断是否可以填写物流信息
        if ($orderSku['refund_info']['uid'] != $uid) {
            throw new \Exception('不可操作该退款单');
        }

        $canFillStatus = [
            mOrderRefund::STATUS_WAIT_REFUND_GOODS,
        ];

        if (!in_array($orderSku['refund_info']['status'], $canFillStatus)) {
            throw new \Exception('不可操作该退款单');
        }

        if (strtotime($orderSku['refund_info']['allow_fill_logistics_close_time']) < time()) {
            throw new \Exception('已过了填写退货信息的时间');
        }

        $shopCourier = sShopCourier::getRefundCourierInfo($data['express_company']);

        //操作退款记录表
        $upData = [
            'express_company' => $shopCourier['courier_name'],
            'express_no' => $data['express_no'],
            'fill_logistics_time' => date('Y-m-d H:i:s', $nowTime),
            'prolong_receipt_time' => '0000-00-00 00:00:00',
            'auto_confirm_receipt_time' => date('Y-m-d H:i:s', $nowTime + mOrderRefund::AUTO_CONFIRM_RECEIPT_TIME),
            'status' => mOrderRefund::STATUS_WAIT_CONFIRM_RECEIPT
        ];
        $result = mOrderRefund::update($upData, ['refund_order_no' => $refundOrderNo]);

        if ($result->rowCount() == 0) {
            throw new \Exception('操作异常');
        }

        //用户填写退货物流单号
        Event::push(Event::ORDER_REFUND_USER_FILL_LOGISTICS, [
            'uid' => $uid,
            'order_no' => $orderSku['order_no'],
            'refund_order_no' => $refundOrderNo,
            'goods_id' => $orderSku['goods_id'],
            'sku_id' => $orderSku['sku_id'],
            'express_company' => $upData['express_company'],
            'express_no' => $upData['express_no'],
            'fill_logistics_time' => $upData['fill_logistics_time'],
            'uniq_idx' => ['refund_order_no', 'event_tag', 'fill_logistics_time']
        ]);

        //增加操作日志
        $result = mOrderOperateLog::createLog($orderSku['shop_id'], $orderSku['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER_REFUND, [
            'operate_type' => mOrderOperateLog::OPERATE_TYPE_REFUNDED_GOODS,
            'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
            'operate_uid' => $uid,
        ], $refundOrderNo, vsprintf('退回商品。快递公司：%s 快递单号：%s 附加说明：%s', [
            $shopCourier['courier_name'],
            $data['express_no'],
            !empty($data['logistics_remark']) ? $data['logistics_remark'] : '无',
        ]), $data['images_content'], $upData);

        if ($result->rowCount() == 0) {
            throw new \Exception('填写物流单号错误');
        }
    }

    public function launchRights($uid, $refundOrderNo, $data)
    {
        $nowTime = date('Y-m-d H:i:s');

        //判断表单是否正确
        if (!vOrderRefund::validate($data, 'launchRights')) {
            $msg = vOrderRefund::firstError();
            throw new \Exception($msg);
        }

        //查询退款单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);

        //判断是否可以取消退款
        if ($orderSku['refund_info']['uid'] != $uid) {
            throw new \Exception('不可操作该退款单');
        }

        if ($orderSku['refund_info']['status'] != mOrderRefund::STATUS_REJECT) {
            throw new \Exception('不可操作该退款单');
        }


        if (strtotime($orderSku['refund_info']['allow_launch_rights_stop_time']) < time()) {
            throw new \Exception('已过了维权申请的时间点');
        }

        //操作退款记录表
        $upData = [
            'rights_remark' => $data['rights_remark'],
            'rights_images_content' => $data['images_content'],
            'launch_rights_time' => $nowTime,
            'rights_into_timeout_time' => date('Y-m-d H:i:s', strtotime($nowTime) + mOrderRefund::RIGHTS_INTO_TIMEOUT_TIME),
            'rights_status' => mOrderRefund::RIGHTS_STATUS_NORMAL,
            'auto_cancel_time' => '0000-00-00 00:00:00'
        ];
        $result = mOrderRefund::update($upData, ['refund_order_no' => $refundOrderNo]);

        if ($result->rowCount() == 0) {
            throw new \Exception('操作异常');
        }

        //用户发起维权事件
        Event::push(Event::ORDER_REFUND_RIGHTS_USER_LAUNCH_SUCCESS, [
            'uid' => $uid,
            'order_no' => $orderSku['order_no'],
            'refund_order_no' => $refundOrderNo,
            'goods_id' => $orderSku['goods_id'],
            'sku_id' => $orderSku['sku_id'],
            'right_remark' => $data['rights_remark'],
            'images_content' => $data['images_content'],
            'now_time' => $nowTime,
            'uniq_idx' => ['refund_order_no', 'event_tag', 'now_time']
        ]);


        $textContent = !empty($data['rights_remark']) ? '理由：' . $data['rights_remark'] : '';

        //增加操作日志
        $result = mOrderOperateLog::createLog($orderSku['shop_id'], $orderSku['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER_RIGHTS, [
            'operate_type' => mOrderOperateLog::OPERATE_TYPE_RIGHTS_LAUNCH,
            'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
            'operate_uid' => $uid,
        ], $refundOrderNo, vsprintf('申请维权。%s', [
            $textContent
        ]), $data['images_content'], $upData);

        if ($result->rowCount() == 0) {
            throw new \Exception('申请维权错误');
        }
    }

    public function fillRightsProof($uid, $refundOrderNo, $data)
    {
        //判断表单是否正确
        if (!vOrderRefund::validate($data, 'fillRightsProof')) {
            $msg = vOrderRefund::firstError();
            throw new \Exception($msg);
        }

        $nowTime = date('Y-m-d H:i:s');

        //查询退款单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);

        //判断是否可以提交凭证
        if ($orderSku['refund_info']['uid'] != $uid) {
            throw new \Exception('不可提交凭证');
        }

        if ($orderSku['refund_info']['status'] != mOrderRefund::STATUS_REJECT) {
            throw new \Exception('不可提交凭证');
        }

        if ($orderSku['refund_info']['rights_status'] != mOrderRefund::RIGHTS_STATUS_PROOFING) {
            throw new \Exception('等待平台介入才可以举证');
        }

        if (strtotime($orderSku['refund_info']['submit_proof_stop_time']) < time()) {
            throw new \Exception('已超过举证时间点');
        }

        //用户填写维权信息事件
        Event::push(Event::ORDER_REFUND_RIGHTS_USER_FILL, [
            'uid' => $uid,
            'order_no' => $orderSku['order_no'],
            'refund_order_no' => $refundOrderNo,
            'goods_id' => $orderSku['goods_id'],
            'sku_id' => $orderSku['sku_id'],
            'proof_remark' => $data['proof_remark'],
            'images_content' => $data['images_content'],
            'now_time' => $nowTime,
            'uniq_idx' => ['refund_order_no', 'event_tag', 'now_time']
        ]);


        $textContent = !empty($data['proof_remark']) ? '：' . $data['proof_remark'] : '';

        //增加操作日志
        $result = mOrderOperateLog::createLog($orderSku['shop_id'], $orderSku['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER_RIGHTS, [
            'operate_type' => mOrderOperateLog::OPERATE_TYPE_SUBMIT_PROOF,
            'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
            'operate_uid' => $uid,
        ], $refundOrderNo, vsprintf('提交凭证%s', [
            $textContent
        ]), $data['images_content']);

        if ($result->rowCount() == 0) {
            throw new \Exception('提交凭证出错');
        }
    }

    public function cancelRights($uid, $refundOrderNo, $needLog = true, $isForce = false)
    {
        $nowTime = date('Y-m-d H:i:s');

        //查询退款单信息
        $orderSku = self::getRefundOrderInfo($refundOrderNo);

        //判断是否可以取消退款
        if ($orderSku['refund_info']['uid'] != $uid) {
            throw new \Exception('不可操作该退款单');
        }

        if (!$isForce) {
            if ($orderSku['refund_info']['status'] != mOrderRefund::STATUS_REJECT) {
                throw new \Exception('不可操作该退款单');
            }


            if (!in_array($orderSku['refund_info']['rights_status'], mOrderRefund::$rightsIngStatusList)) {
                throw new \Exception('不可操作该维权单');
            }

        }


        if ($orderSku['refund_info']['rights_status'] > 0) {
            //操作退款记录表
            $result = mOrderRefund::update([
                'rights_cancel_time' => $nowTime,
                'rights_status' => mOrderRefund::RIGHTS_STATUS_CANCEL,
            ], ['refund_order_no' => $refundOrderNo]);
        }


        if ($needLog) {
            //增加操作日志
            $result = mOrderOperateLog::createLog($orderSku['shop_id'], $orderSku['order_no'], mOrderOperateLog::TRADE_TYPE_ORDER_RIGHTS, [
                'operate_type' => mOrderOperateLog::OPERATE_TYPE_RIGHTS_CANCEL,
                'operate_user_type' => mOrderOperateLog::OPERATE_USERTYPE_USER,
                'operate_uid' => $uid,
            ], $refundOrderNo, '取消维权', '');

            if ($result->rowCount() == 0) {
                throw new \Exception('取消维权出错');
            }
        }

    }

    /**
     * @param $refundOrderNo
     * @param $refundAmount
     * @param $refundIntegral
     * @param $refundRmb
     * 插入到退款处理的队列中
     */
    protected function intoQueue($uid, $shopId, $orderNo, $refundOrderNo, $data)
    {
        $data = array_merge($data, [
            'uid' => $uid,
            'shop_id' => $shopId,
            'order_no' => $orderNo,
            'refund_order_no' => $refundOrderNo,
            'addtime' => date('Y-m-d H:i:s')
        ]);

        $result = mOrderRefundQueue::insert($data);

        if ($result->rowCount() == 0) {
            throw new \Exception('提交失败');
        }

        return mOrderRefundQueue::id();
    }


    //订单sku信息
    protected static function getOrderSkuInfo($uid, $orderNo, $skuId, $master = true)
    {

        $data = [];


        if ($master) {
            $orderInfo = mOrder::getOrderInfoFromMaster($orderNo);
        } else {
            $orderInfo = mOrder::getOrderInfo($orderNo);
        }

        if (empty($orderInfo)) {
            throw new \Exception('订单不存在');
        }

        if ($orderInfo['uid'] != $uid) {
            throw new \Exception('订单不存在');
        }

        if ($orderInfo['status'] == mOrder::STATUS_DEL) {
            throw new \Exception('订单状态不正确，不可申请退款');
        }

        if ($master) {
            $data = mOrderGoods::getSkuInfoFromMaster($orderNo, $skuId);
        } else {
            $data = mOrderGoods::getSkuInfo($orderNo, $skuId);
        }


        $data['order_info'] = $orderInfo;

        return $data;

    }

    protected static function getRefundOrderInfo($refundOrderNo, $master = true)
    {
        $info = mOrderRefund::getRefundOrderInfoFromMaster($refundOrderNo);

        if (empty($info)) {
            throw new \Exception('退款单不存在');
        }

        $orderSku = self::getOrderSkuInfo($info['uid'], $info['order_no'], $info['sku_id'], $master);

        $orderSku['refund_info'] = $info;

        return $orderSku;
    }

    /**
     * @param $orderSku
     * 判断是否可以修改退款申请单
     */

    protected static function checkCanChangeApply(&$orderSku)
    {
        //如果退款单状态不是被拒绝，则不允许修改退款单
        if ($orderSku['refund_info']['status'] != mOrderRefund::STATUS_REJECT) {
            return false;
        }

        $rejectTime = strtotime($orderSku['refund_info']['allow_change_time']);

        //如果不是在被拒绝的7天内，则不允许修改退款申请
        if ($rejectTime < time()) {
            return false;
        }

        return true;
    }


    /**
     * 判断申请的该SKUID是否可以退款
     * return true 可以退款
     *        false 不可退款
     */
    protected static function checkCanApplyRefund(&$orderSku)
    {
        //商品金额=0不可以退款
        if ($orderSku['goods_amount'] <= 0) {

            tLog::refund_refund_info('判断是否可以申请退款，不可退款，原因：下单商品金额为0', [
                'uid' => $orderSku['uid'],
                'order_no' => $orderSku['order_no'],
                'sku_id' => $orderSku['sku_id']
            ]);

            return false;
        }


        //确认收货后的一段时间内可以申请退款
        if ($orderSku['order_info']['status'] == mOrder::STATUS_SUCCESS) {
            if (strtotime($orderSku['order_info']['canrefund_stop_time']) < time()) {

                tLog::refund_refund_info('判断是否可以申请退款，不可退款，原因：退款时间超时', [
                    'uid' => $orderSku['uid'],
                    'order_no' => $orderSku['order_no'],
                    'sku_id' => $orderSku['sku_id']
                ]);

                return false;
            }
        }

        //订单状态只有这三种状态可以申请退款
        if (!in_array($orderSku['order_info']['status'], [mOrder::STATUS_WAIT_SEND, mOrder::STATUS_SEND_OUT, mOrder::STATUS_SEND_PART_OUT, mOrder::STATUS_SUCCESS])) {

            tLog::refund_refund_info('判断是否可以申请退款，不可退款，原因：订单状态不允许退款', [
                'uid' => $orderSku['uid'],
                'order_no' => $orderSku['order_no'],
                'sku_id' => $orderSku['sku_id'],
                'order_status' => $orderSku['order_info']['status']
            ]);


            return false;
        }

        //如果不是修改退款单，则需要判断7天内是否有拒绝的退款单、且需要判断sku退款的状态
        if (!isset($orderSku['refund_info']['refund_order_no']) || empty($orderSku['refund_info']['refund_order_no'])) {

            //判断7天内是否有拒绝的退款单
            $before7Days = date('Y-m-d H:i:s', strtotime('-7 days'));

            $list = mOrderRefund::get("*", [
                'order_no' => $orderSku['order_no'],
                'sku_id' => $orderSku['sku_id'],
                'status' => mOrderRefund::STATUS_REJECT,
                'reject_time[>]' => $before7Days,
            ]);


            if (!empty($list)) {

                tLog::refund_refund_info('判断是否可以申请退款，不可退款，原因：7天内有被拒绝的退款申请', [
                    'uid' => $orderSku['uid'],
                    'order_no' => $orderSku['order_no'],
                    'sku_id' => $orderSku['sku_id'],
                    'reject_list' => $list
                ]);


                return false;
            }


            if ($orderSku['refund_status'] == mOrderGoods::REFUND_STATUS_CAN_NOT_REFUND) {

                tLog::refund_refund_info('判断是否可以申请退款，不可退款，原因：有正在进行的退款，或该sku已退款', [
                    'uid' => $orderSku['uid'],
                    'order_no' => $orderSku['order_no'],
                    'sku_id' => $orderSku['sku_id'],
                    'refund_order_no' => $orderSku['refund_info']['refund_order_no'],
                    'sku_refund_status' => $orderSku['refund_status']
                ]);

                return false;
            }

        }

        return true;

    }

    protected static function checkRefundShippingAmount($orderNo, $skuId, $shippingAmount, $refundReason = -1)
    {
        $shippingFee = 0;
        $isLastedApply = true;

        //获取除了当前skuId之外的其他退款申请是否退了运费，如果退运费则返回退了的总额
        $refundedShippingFee = self::getCanRefundShippingFee($orderNo, $skuId);

        $canRefundFee = Amount::format($shippingAmount - $refundedShippingFee);

        if ($canRefundFee < 0) {
            $canRefundFee = 0;
        }

        //如果可退运费不足，则直接返回可以申请的运费退款为0
        if ($canRefundFee <= 0) {
            return 0;
        }

        //如果选择的退款理由为退运费，则直接可以计算可退运费的金额
        if ($refundReason == mOrderRefund::REFUND_REASON_30) {
            return $canRefundFee;
        }

        $orderGoods = mOrderGoods::getInfosByOrderNo($orderNo, ['sku_id', 'shipping_amount']);
        $orderGoodsShippingArr = [];
        $orderAllGoodsShippingAmount = 0;
        $skuIds = [];
        foreach ($orderGoods as $row) {
            $orderGoodsShippingArr[$row['sku_id']] = $row['shipping_amount'];
            $orderAllGoodsShippingAmount = bcadd($orderAllGoodsShippingAmount, $row['shipping_amount'], 2);
            $skuIds[] = $row['sku_id'];
        }

        //sku运费平摊之后，需要退款的时候退运费。如果sku未平摊运费，按之前逻辑，退最后一件商品才能退运费
        if ($orderAllGoodsShippingAmount > 0) {//如果orderGoods有商品平摊运费,则退款需要退商品运费

            $skuShippingAmount = $orderGoodsShippingArr[$skuId];

            $shippingFee = min($skuShippingAmount, $canRefundFee);

        } else {//如果orderGoods没有商品平摊当前订单运费。则走之前逻辑，退最后一件商品时才能退运费


            if (count($skuIds) > 1) {

                $otherSkuIds = array_filter($skuIds, function ($v) use ($skuId) {
                    return $v != $skuId;
                });


                $refundSku = mOrderRefund::select(['sku_id'], [
                    'order_no' => $orderNo,
                    'sku_id[!]' => $skuId,
                    'status[!]' => [mOrderRefund::STATUS_CANCEL, mOrderRefund::STATUS_RETURN_GOODS_CANCEL]]);
                $refundSkuIds = array_values($refundSku);

                if (count($otherSkuIds) != count($refundSkuIds)) {
                    $isLastedApply = false;
                }


            }

            //是最后一个，则退运费
            if ($isLastedApply) {

                $shippingFee = $canRefundFee;

            }
        }

        return $shippingFee;

    }

    protected static function getCanRefundShippingFee($orderNo, $skuId)
    {
        $refundedShippingFee = mOrderRefund::sum('refund_shipping_amount', ['order_no' => $orderNo, 'sku_id[!]' => $skuId, 'status[!]' => [mOrderRefund::STATUS_CANCEL, mOrderRefund::STATUS_RETURN_GOODS_CANCEL]]);

        return $refundedShippingFee;

    }

    protected static function getSkuCanRefundAmount(&$orderSku, $applyAmount = null, $refundReason = -1)
    {
        bcscale(2);
        $data = [
            //申请的退款金额,客户端填写的数，可能包含运费，也可能不包括运费
            'refund_apply_amount' => 0,
            //最大的可退金额，如果有运费则包含运费
            'refund_max_amount' => 0,
            //此次退款按比例退的积分数额
            'refund_integral' => 0,
            //此次退款按比例退的积分金额
            'refund_integral_amount' => 0,
            //此次退款按比例退的红包金额
            'refund_packet_amount' => 0,
            //此次退款的支付金额，不包括运费
            'refund_sku_pay_amount' => 0,
            //此次退款的支付金额+运费金额
            'refund_rmb_total' => 0,
            //此次退款的运费金额
            'refund_shipping_fee' => 0,
            //此次退款的佣金数
            'refund_commission_amount' => 0,
            //此次退款的优惠券退的数量
            'refund_coupon_amount' => 0,
            //此次退款的补贴金额
            'refund_activity_allowance' => 0,
        ];

        //判断是否退运费
        $data['refund_shipping_fee'] = self::checkRefundShippingAmount($orderSku['order_no'], $orderSku['sku_id'], $orderSku['order_info']['shipping_amount'], $refundReason);


        //如果申请原因为只退运费，那么其他的为0，只有退运费
        if ($refundReason == mOrderRefund::REFUND_REASON_30) {

            if (!is_null($applyAmount)) {
                $data['refund_shipping_fee'] = min([$data['refund_shipping_fee'], $applyAmount]);
            }

            $data['refund_apply_amount'] = $data['refund_shipping_fee'];
            $data['refund_max_amount'] = $data['refund_shipping_fee'];
            $data['refund_rmb_total'] = $data['refund_shipping_fee'];

            return $data;
        }


        //当退款原因为退差价时，退的金额最大只能退pay_amount-0.01
        $calBYReason = function ($amount) use ($refundReason) {
            if ($refundReason == mOrderRefund::REFUND_REASON_35) {
                return $amount - 0.01;
            }
            return $amount;
        };


        //当前SKU可以退款金额
        if (!empty($applyAmount)) {

            //申请金额
            $data['refund_apply_amount'] = Amount::format($applyAmount);

            $canMaxRefund = bcadd($orderSku['pay_amount'], $data['refund_shipping_fee']);

            //计算退的金额和是否退运费

            if (bccomp($applyAmount, strval($canMaxRefund)) <= 0) {

                if ($refundReason == mOrderRefund::REFUND_REASON_35) {
                    if (bcadd($applyAmount, 0.01) == $canMaxRefund) {
                        $applyAmount = $applyAmount + 0.01;
                    }
                }

                if ($applyAmount <= $orderSku['pay_amount']) {

                    if ($applyAmount == $orderSku['pay_amount']) {
                        $applyAmount = $calBYReason($orderSku['pay_amount']);
                    }

                    //如果申请退款金额小于商品金额，运费不退
                    $data['refund_shipping_fee'] = 0;

                } elseif ($applyAmount > $orderSku['pay_amount']) {
                    if ($data['refund_shipping_fee'] > 0) {
                        //运费等于申请金额-商品金额
                        $refundShip = Amount::format($applyAmount - $orderSku['pay_amount']);

                        $data['refund_shipping_fee'] = min($refundShip, $data['refund_shipping_fee']);
                    }

                    //申请金额=商品金额
                    $applyAmount = $calBYReason($orderSku['pay_amount']);

                }

            } else {
                $data['refund_apply_amount'] = 0;
                $data['refund_shipping_fee'] = 0;
                return $data;
            }


            //申请的退款金额和商品支付金额进行一个比例计算
            $refundRate = $orderSku['pay_amount'] > 0 ? ($applyAmount / $orderSku['pay_amount']) : 1;

            //是否只退现金
            $onlyCash = ($refundReason == mOrderRefund::REFUND_REASON_35 && $applyAmount < $orderSku['pay_amount']) ? true : false;

            //如果只退现金，则下面的不计算
            if (!$onlyCash) {
                $data['refund_integral'] = (int)($orderSku['integral'] * $refundRate);
                $data['refund_integral_amount'] = Amount::format($orderSku['integral_amount'] * $refundRate);
                $data['refund_packet_amount'] = Amount::format($orderSku['packet_amount'] * $refundRate);
                $data['refund_coupon_amount'] = Amount::format($orderSku['coupon_amount'] * $refundRate);
                $data['refund_activity_allowance'] = Amount::format($orderSku['activity_allowance'] * $refundRate);
            }

            $data['refund_sku_pay_amount'] = Amount::format($orderSku['pay_amount'] * $refundRate);

            $data['refund_commission_amount'] = self::calCommissionAmount($data, $orderSku);

        } else {

            $orderSku['pay_amount'] = $calBYReason($orderSku['pay_amount']);

            $data['refund_apply_amount'] = Amount::format($orderSku['pay_amount'] + $data['refund_shipping_fee']);
            $data['refund_integral'] = $orderSku['integral'];
            $data['refund_integral_amount'] = $orderSku['integral_amount'];
            $data['refund_packet_amount'] = $orderSku['packet_amount'];
            $data['refund_coupon_amount'] = $orderSku['coupon_amount'];
            $data['refund_activity_allowance'] = $orderSku['activity_allowance'];
            $data['refund_sku_pay_amount'] = Amount::format($orderSku['pay_amount']);

            //佣金比例
            $data['refund_commission_amount'] = Amount::format($orderSku['commissions']);
        }


        //计算最大可退金额
        $data['refund_max_amount'] = Amount::format($orderSku['pay_amount'] + $data['refund_shipping_fee']);

        $data['refund_rmb_total'] = Amount::format($data['refund_sku_pay_amount'] + $data['refund_shipping_fee']);

        return $data;

    }

    protected static function calCommissionAmount($data, $orderSku)
    {
        $calVal = (
                ($data['refund_sku_pay_amount'] + $data['refund_integral_amount'] + $data['refund_coupon_amount'] + $data['refund_packet_amount'] + $data['refund_activity_allowance'])
                /
                ($orderSku['pay_amount'] + $orderSku['integral_amount'] + $orderSku['coupon_amount'] + $orderSku['packet_amount'] + $orderSku['activity_allowance'])
            ) * $orderSku['commissions'];

        return Amount::format($calVal);
    }

    public function getRefundLogList($uid, $refundOrderNo)
    {
        $result = [];

        $orderRefund = self::getRefundOrderInfo($refundOrderNo, false);

        if ($orderRefund['uid'] != $uid) {
            throw new \Exception('您没有查看此退款单号的权限');
        }

        $logList = mOrderOperateLog::getLogList(['refund_order_no' => $refundOrderNo, 'trade_type[!]' => mOrderOperateLog::TRADE_TYPE_ORDER, 'status' => mOrderOperateLog::STATUS_NORMAL, 'ORDER' => ['addtime' => 'DESC']]);

        $uids = array_filter(array_column($logList, 'operate_uid'), function ($v) {
            if ($v != 0) {
                return true;
            }
            return false;
        });

        $sysUserInfo = sUser::getSysUserInfo();

        $userInfos = sUser::getUsers($uids);

        array_walk($logList, function ($v, $k) use (&$result, $userInfos, $sysUserInfo) {
            $result[$k]['add_time'] = $v['addtime'];
            $result[$k]['text_content'] = $v['text_content'];
            $result[$k]['images_content'] = $v['images_content_url'];
            $result[$k]['user_info'] = [
                'user_type' => $v['operate_user_type'],
                'uid' => $v['operate_uid'],
                'name' => $v['operate_user_type'] == mOrderOperateLog::OPERATE_USERTYPE_SYS ? $sysUserInfo['nick'] : $userInfos[$v['operate_uid']]['nick'],
                'avatar_small' => $v['operate_user_type'] == mOrderOperateLog::OPERATE_USERTYPE_SYS ? $sysUserInfo['avatar_small'] : $userInfos[$v['operate_uid']]['avatar_small']
            ];
        });
        return $result;
    }

    public function getDetail($refundOrderNo, $uid, $reason = -1)
    {
        $data = [];
        $refundInfo = mOrderRefund::getRefundOrderInfo($refundOrderNo);
        if ($refundInfo['uid'] != $uid) {
            throw new \Exception('您没有查看此退款单号详情的权限');
        }

        $skuInfo = self::getOrderSkuInfo($uid, $refundInfo['order_no'], $refundInfo['sku_id'], false);
        $smallEnergyInfo = csSmallEnergy::getSmallEnergyInfoByShopId($refundInfo['shop_id'], ['pre_sale_reception_group_id']);
        $skuPriceInfo = mGoodsSku::getSkuField(['price'], $skuInfo['sku_id']);
        $shopInfo = mShopBasicInfo::getShopInfo($refundInfo['shop_id'], ['name']);

        $calRefund = $this->getSkuCanRefundAmount($skuInfo, null, $reason);

        $arrayTime = [
            'apply_time' => $refundInfo['addtime'],
            'now_time' => time(),
            'auto_agree_time' => strtotime($refundInfo['auto_agree_time']),
            'submit_proof_stop_time' => strtotime($refundInfo['submit_proof_stop_time']),
            'auto_logistics_close_time' => strtotime($refundInfo['allow_fill_logistics_close_time']),
            'auto_confirm_receipt_time' => strtotime($refundInfo['auto_confirm_receipt_time'])
        ];

        $data['refund_order_no'] = $refundInfo['refund_order_no'];
        $data['order_no'] = $refundInfo['order_no'];
        $data['type_refund'] = $refundInfo['type_refund'];
        $data['type_refund_desc'] = $refundInfo['type_refund_desc'];
        $data['reason'] = $refundInfo['reason'];
        $data['reason_desc'] = $refundInfo['reason_desc'];
        $data['remark'] = $refundInfo['reject_remark'];
        $data['company_group_id'] = self::COMPANY_GROUP_ID;
        $data['shop_info'] = [
            'shop_id' => $refundInfo['shop_id'],
            'shop_name' => $shopInfo['name'],
            'se_group_id' => $smallEnergyInfo['pre_sale_reception_group_id'] ?: csSmallEnergy::GROUP_ID,
            'small_energy' => [
                'pre_sale_reception_group_id' => $smallEnergyInfo['pre_sale_reception_group_id'] ?: csSmallEnergy::GROUP_ID
            ]
        ];

        $data['rights_judge_result'] = $refundInfo['rights_judge_result'];
        $data['rights_judge_result_desc'] = $refundInfo['rights_judge_result_desc'];
        $data['rights_process_method'] = $refundInfo['rights_process_method'];
        $data['rights_process_method_desc'] = $refundInfo['rights_process_method_desc'];
        $data['rights_judge_remark'] = $refundInfo['rights_judge_remark'];


        $data['status'] = $refundInfo['status'];
        $data['status_desc'] = $refundInfo['status_desc'];
        $data['rights_status'] = $refundInfo['rights_status'];
        $data['rights_status_desc'] = $refundInfo['rights_status_desc'];

        $data['v_status'] = $refundInfo['v_h5_status'];
        $data['v_status_desc'] = $refundInfo['v_h5_status_desc'];
        $data['refund_images_content'] = $refundInfo['refund_images_content_url'];

        $goodsInfo = [];
        $goodsInfo['sku_id'] = $skuInfo['sku_id'];
        $goodsInfo['goods_id'] = $skuInfo['goods_id'];
        $goodsInfo['title'] = $skuInfo['title'];
        $goodsInfo['sku_desc'] = $skuInfo['sku_desc'];
        $goodsInfo['cover_img'] = $skuInfo['cover_img_thumb_url'];
        $goodsInfo['refund_amount'] = $refundInfo['refund_amount'];
        $goodsInfo['receipt_status'] = $refundInfo['receipt_status'];
        $goodsInfo['receipt_status_desc'] = $refundInfo['receipt_status_desc'];
        $goodsInfo['shipping_fee'] = $refundInfo['refund_shipping_amount'];
        $goodsInfo['order_status'] = $skuInfo['order_info']['status'];

        if ($skuInfo['order_info']['is_package_delivery'] == mOrder::IS_PACKAGE_DELIVERY_YES) {
            $skuIsShip = clsOrderGoods::checkSkuIsDeliveryIncludePartShip($refundInfo['order_no'], $skuInfo['sku_id'], $skuInfo['order_info']);
            if ($skuIsShip === 1) {
                $goodsInfo['order_status'] = mOrder::STATUS_WAIT_SEND;
            } elseif ($skuIsShip === 2) {
                $goodsInfo['order_status'] = mOrder::STATUS_SEND_OUT;
            }
        }


        $goodsInfo['refund_remark'] = $refundInfo['refund_remark'];
        $goodsInfo['sku_price'] = $skuPriceInfo['price'];

        $data['sku_info'] = $goodsInfo;


        $data['cal_refund'] = $calRefund;

        $data['refund_address'] = [
            'address' => $refundInfo['consignee_address'],
            'contact' => $refundInfo['consignee_name'],
            'phone' => $refundInfo['consignee_phone'],
            'notice' => $refundInfo['consignee_notice']
        ];
        $data['time_info'] = $this->formatTime($arrayTime);
        return $data;
    }

    protected function formatTime($arrayTime)
    {
        $timeResult = [];
        foreach ($arrayTime as $field => $time) {
            if ($time > 0) {
                $timeResult[$field] = $time;
            }
        }
        return $timeResult;
    }

    /**
     * 判断是否有处理中的退款申请
     * return  1无处理中的退款申请
     *         2有处理中的退款申请
     *         3有维权中的退款申请
     *         4有待审核的退款申请
     * */
    public function checkOrderHasRefunding($orderNoAndStatusList = [], $action = 'mgtShip', $needList = false, $whereSkuIds = [])
    {
        $where = [];
        $result = [];

        $orderNoList = array_keys($orderNoAndStatusList);


        //是否有处理中的退款申请，返回一个二维数组，是有处理中的退款申请
        $refundingList = mOrderRefund::select(['order_no', 'refund_order_no'], array_merge(['order_no' => $orderNoList, 'status' => mOrderRefund::$refundIngStatusList], $whereSkuIds));

        //整理数据
        if (!empty($refundingList)) {
            $refundingList = array_column($refundingList, null, 'order_no');
        }

        //有维权中的退款申请
        $rightsingList = mOrderRefund::select(['order_no', 'refund_order_no'], array_merge(['order_no' => $orderNoList, 'rights_status' => mOrderRefund::$rightsIngStatusList], $whereSkuIds));

        if (!empty($rightsingList)) {
            $rightsingList = array_column($rightsingList, null, 'order_no');
        }


        //是否有待审核的退款申请，只要任意一个商品有，则不允许发货并弹出提示。
        if ($action == 'mgtShip') {
            $refundWaitApplyList = mOrderRefund::select(['order_no', 'refund_order_no'], array_merge(['order_no' => $orderNoList, 'status' => mOrderRefund::STATUS_NORMAL], $whereSkuIds));

            if (!empty($refundWaitApplyList)) {
                $refundWaitApplyList = array_column($refundWaitApplyList, null, 'order_no');
            }
        }

        foreach ($orderNoAndStatusList as $orderNo => $orderStatus) {

            tLog::refund_refund_info('判断是否有退款中的行为时，有待处理的退款申请', [
                'order_no' => $orderNo,
                'order_status' => $orderStatus,
                'refund_wait_List' => !empty($refundWaitApplyList[$orderNo]) ? $refundWaitApplyList[$orderNo] : [],
            ]);

            if (!in_array($orderStatus, [mOrder::STATUS_WAIT_SEND, mOrder::STATUS_SEND_OUT])) {
                continue;
            }

            if (!in_array($action, ['mgtShip', 'userReceipt'])) {
                continue;
            }

            if ($orderStatus == mOrder::STATUS_WAIT_SEND && $action == 'mgtShip') {
                if (!empty($refundWaitApplyList[$orderNo])) {
                    $result[$orderNo] = self::REFUND_WAIT_APPLY;

                    continue;
                }
            }


            if (!empty($rightsingList[$orderNo])) {
                //有维权中的退款申请
                $result[$orderNo] = self::REFUNDING_RIGHTS_IN;

                continue;
            }

            if (!empty($refundingList[$orderNo])) {

                //有处理中的退款申请
                $result[$orderNo] = self::REFUNDING_YES;

                continue;
            } else {

                $result[$orderNo] = self::REFUNDING_NO;

                continue;
            }
        }

        if (count($orderNoAndStatusList) == 1 && !$needList) {

            if (empty($result)) {
                return 0;
            }

            $value = array_values($result);

            return $value[0];
        }


        return $result;
    }

    /**
     * 取消指定订单下面的所有退款单申请
     */

    public function cancelOrderRefundList($orderNo, $refundJob = [], $whereSkuIds = [])
    {
        $where = [
            'order_no' => $orderNo,
            'OR' => [
                'status' => mOrderRefund::$refundIngStatusList,
                'rights_status' => mOrderRefund::$rightsIngStatusList,
            ]
        ];

        $where = array_merge($where, $whereSkuIds);

        $refundList = mOrderRefund::select('*', $where);

        if (empty($refundList) || empty($refundJob)) {
            return false;
        }

        foreach ($refundList as $refund) {
            foreach ($refundJob as $job) {
                //维权取消
                if ($job == 'cancel_rights') {
                    try {
                        $this->cancelRights($refund['uid'], $refund['refund_order_no'], false);
                    } catch (\Exception $e) {

                    }
                }

                //退款取消
                if ($job == 'cancel_refund') {
                    try {
                        $this->cancelRefund($refund['uid'], $refund['refund_order_no'], true);
                    } catch (\Exception $e) {

                    }
                }
            }

        }

    }

    /**
     * 根据订单号判断该订单是否可以关闭
     */

    public function repairOrderByOrderNo($orderNo)
    {
        $order = mOrder::getOrderInfoFromMaster($orderNo);

        //判断订单是否关闭
        if ($order['status'] == mOrder::STATUS_CLOSE) {
            return true;
        }

        //查询订单的总成功的退款金额
        $refundSum = mOrderRefund::get(['refund_sum' => Medoo::raw('SUM(refund_rmb+refund_shipping_amount)')], ['order_no' => $orderNo, 'status' => [
            mOrderRefund::STATUS_REFUNDING, mOrderRefund::STATUS_COMPLETE
        ]
        ]);

        //如果没有合计退款金额，则不需要继续处理
        if ($refundSum == null) {
            return false;
        }

        //计算订单总金额
        $orderSum = $order['pay_amount'];

        //退款金额=订单总金额，则关闭订单
        tLog::refund_refund_info('如果退款金额=订单总金额,订单状态改为交易关闭', [
            'order_no' => $orderNo,
            'order_sum' => $orderSum,
            'refund_sum' => $refundSum['refund_sum'],
            'is_close' => (int)($orderSum == $refundSum['refund_sum'])
        ]);

        if ($orderSum == $refundSum['refund_sum']) {


            $result = mOrder::update(['status' => mOrder::STATUS_CLOSE], ['order_no' => $orderNo, 'status[!]' => mOrder::STATUS_CLOSE]);

            //因订单全额退款导致订单关闭
            Event::push(Event::ORDER_CLOSE_ORDER_SUCCESS, [
                'order_no' => $orderNo,
                'reason' => 3,
                'uniq_idx' => ['order_no', 'event_tag', 'reason']
            ]);
        } else {
            if ($order['status'] == mOrder::STATUS_SUCCESS) {
                return true;
            }

            $skuSum = mOrderGoods::count(['order_no' => $orderNo]);

            $orderRefund = mOrderRefund::select(['sku_id', 'refund_rmb', 'refund_shipping_amount'], [
                'order_no' => $orderNo, 'status' => [
                    mOrderRefund::STATUS_REFUNDING, mOrderRefund::STATUS_COMPLETE
                ]
            ]);

            if ($skuSum == count($orderRefund)) {

                $refundSum = 0;

                array_map(function ($v) use (&$refundSum) {
                    $refundSum += ($v['refund_rmb'] + $v['refund_shipping_amount']);
                }, $orderRefund);

                if ($refundSum < $orderSum) {

                    $confirmTime = date('Y-m-d H:i:s');

                    $result = mOrder::update(['confirm_time' => $confirmTime, 'status' => mOrder::STATUS_SUCCESS], ['order_no' => $orderNo]);

                    tLog::refund_refund_info('如果退款金额<订单总金额,订单状态改为交易成功', [
                        'order_no' => $orderNo,
                        'refund_sum' => $refundSum,
                        'order_sum' => $orderSum,
                    ]);

                    if ($result->rowCount() > 0) {

                        tLog::refund_refund_info('如果退款金额<订单总金额,订单状态改为交易成功，需要进行结算调用，调用参数如下', [
                            'order_no' => $orderNo,
                            'afterConfirmOrderSettlement' => [
                                'shop_id' => $order['shop_id'],
                                'order_no' => $order['order_no'],
                                'pay_amount' => $order['pay_amount'],
                                'integral_amount' => $order['integral_amount'],
                                'coupon_amount' => $order['coupon_amount'],
                                'activity_allowance' => $order['activity_allowance'],
                                'discount_amount' => $order['discount_amount'],
                                'commissions' => $order['commissions'],
                                'pay_way' => $order['pay_way'],
                                'shipping_amount' => $order['shipping_amount'],
                                'confirm_time' => $confirmTime,
                                'issys' => 1
                            ]
                        ]);

                        clsOrder::afterConfirmOrderSettlement($order['shop_id'], $order['order_no'], $order['pay_amount'], $order['integral_amount'], $order['coupon_amount'], $order['activity_allowance'], $order['packet_amount'], $order['commissions'], $order['pay_way'], $order['shipping_amount'], $confirmTime, true);

                    }


                }

            }
        }


    }

    /**
     * 分单发货的订单，退款完成后，更新订单状态
     */
    public static function updateOrderStatusByPartShip($orderNo, $orderStatus)
    {
        if ($orderStatus == mOrder::STATUS_SEND_PART_OUT) {
            $nowTime = time();

            //在已发货商品中，非全部退款完成/或者打款中
            $allShipRefundSuccess = false;

            //在未发货商品中，非全部退款完成/或者打款中
            $allNoShipRefundSuccess = false;

            //获取指定单号下所有skuId列表
            $orderSkuIds = mOrderGoods::getSkuIds($orderNo);

            //获取指定订单号下已进行分单发货的sku列表
            $packageSkuIds = mOrderPackage::getAllPackageSkuIds($orderNo);

            //没有发货的skuIds
            $noShipSkuIds = array_diff($orderSkuIds, $packageSkuIds);


            if (!empty($packageSkuIds)) {
                $succShipedList = mOrderRefund::getRefundSuccessList($orderNo, $packageSkuIds);

                if (count($packageSkuIds) == count($succShipedList)) {
                    $allShipRefundSuccess = true;
                }

            }

            if (!empty($noShipSkuIds)) {
                $succNoShipedList = mOrderRefund::getRefundSuccessList($orderNo, $noShipSkuIds);

                if (count($noShipSkuIds) == count($succNoShipedList)) {
                    $allNoShipRefundSuccess = true;
                }
            }


            //没有未发货商品  或  全部未发货商品退款完成/打款中
            if (empty($noShipSkuIds) || $allNoShipRefundSuccess === true) {
                if (empty($packageSkuIds) || $allShipRefundSuccess === true) {
                    (new OrderRefund())->repairOrderByOrderNo($orderNo);

                }

                if (!empty($packageSkuIds) && !$allShipRefundSuccess) {
                    $data = [];
                    $data['status'] = mOrder::STATUS_SEND_OUT;
                    $data['delivery_time'] = date('Y-m-d H:i:s', $nowTime);
                    $data['autoconfirm_time'] = date('Y-m-d H:i:s', $nowTime + mOrder::MAX_WAIT_AUTO_CONFIRM_TIME);


                    mOrder::updateData($data, ['order_no' => $orderNo]);

                }
            }


        }
    }


    /**
     * 结算系统对接
     */

    protected function orderRefundIntoSettlementTransaction($shopId, &$orderSku, $queueId, $nowTime, $isSys)
    {

        try {
            //结算系统对接
            if ($orderSku['order_info']['status'] == mOrder::STATUS_SUCCESS) {

                $type = 2;

                sSettlementTransaction::afterRefundSuccess($shopId, $orderSku['order_no'], $orderSku['refund_order_no'], 2, $orderSku['refund_info']['goods_id'], $orderSku['refund_info']['sku_id'], $orderSku['refund_info']['title'] . '-' . $orderSku['refund_info']['sku_desc'], $orderSku['refund_info']['refund_rmb'] + $orderSku['refund_info']['refund_shipping_amount'], $orderSku['refund_info']['refund_shipping_amount'], $orderSku['refund_info']['refund_integral_amount'], $orderSku['refund_info']['refund_coupon_amount'], $orderSku['refund_info']['refund_activity_allowance'], $orderSku['refund_info']['refund_packet_amount'], date('Y-m-d H:i:s', $nowTime), $orderSku['order_info']['pay_way'], (bool)$isSys, $orderSku['refund_info']['refund_commission_amount']);

                //更新退款对列表
                $result = mOrderRefundQueue::update([
                    'refund_commission_amount_time' => date('Y-m-d H:i:s', $nowTime),
                    'refund_commission_amount_status' => mOrderRefundQueue::REFUND_COMMISSION_STATUS_COMPLETE
                ], ['id' => $queueId]);

            } else {
                $type = 1;

                sSettlementTransaction::afterRefundSuccess($shopId, $orderSku['order_no'], $orderSku['refund_order_no'], 1, $orderSku['refund_info']['goods_id'], $orderSku['refund_info']['sku_id'], $orderSku['refund_info']['title'] . '-' . $orderSku['refund_info']['sku_desc'], $orderSku['refund_info']['refund_rmb'] + $orderSku['refund_info']['refund_shipping_amount'], $orderSku['refund_info']['refund_shipping_amount'], $orderSku['refund_info']['refund_integral_amount'], $orderSku['refund_info']['refund_coupon_amount'], $orderSku['refund_info']['refund_activity_allowance'], $orderSku['refund_info']['refund_packet_amount'], date('Y-m-d H:i:s', $nowTime), $orderSku['order_info']['pay_way'], (bool)$isSys);
            }

            //加日志
            tLog::refund_refund_info('退款成功，调用结算接口,订单状态为确认收货', [
                'refund_order_no' => $orderSku['refund_order_no'],
                'params' => [
                    'shop_id' => $shopId,
                    'queue_id' => $queueId,
                    'nowTime' => $nowTime,
                    'issys' => $isSys
                ],
                'sSettlementTransaction::afterRefundSuccess' => [
                    'shop_id' => $shopId,
                    'order_no' => $orderSku['order_no'],
                    'refund_order_no' => $orderSku['refund_order_no'],
                    'type' => $type,
                    'goods_id' => $orderSku['refund_info']['goods_id'],
                    'sku_id' => $orderSku['refund_info']['sku_id'],
                    'title' => $orderSku['refund_info']['title'] . '-' . $orderSku['refund_info']['sku_desc'],
                    'refund_amount' => $orderSku['refund_info']['refund_rmb'] + $orderSku['refund_info']['refund_shipping_amount'],
                    'refund_shipping_amount' => $orderSku['refund_info']['refund_shipping_amount'],
                    'refund_integral_amount' => $orderSku['refund_info']['refund_integral_amount'],
                    'refund_packet_amount' => $orderSku['refund_info']['refund_packet_amount'],
                    'refund_coupon_amount' => $orderSku['refund_info']['refund_coupon_amount'],
                    'refund_activity_allowance' => $orderSku['refund_info']['refund_activity_allowance'],
                    'confirmTime' => date('Y-m-d H:i:s', $nowTime),
                    'pay_way' => $orderSku['order_info']['pay_way'],
                    'is_sys' => $isSys,
                    'refund_commission_amount' => ($type == 2) ? $orderSku['refund_info']['refund_commission_amount'] : '因type=1则未传'
                ]
            ]);

        } catch (\Exception $e) {

        }


    }

    //同步order和order_goods表中的refund_amount,refunded_amount,refunded_shipping_amount记录
    protected static function syncRefundAmountRecord($orderNo, $skuId, $orderGoodsUpData = [], $orderUpData = [])
    {

        //修改order_goods表
        if (!empty($orderGoodsUpData)) {
            mOrderGoods::update($orderGoodsUpData, ['order_no' => $orderNo, 'sku_id' => $skuId]);
        }

        //修改order表
        if (!empty($orderUpData)) {
            mOrder::update($orderUpData, ['order_no' => $orderNo]);
        }


    }


}